home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / lfsrecov / desc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-17  |  10.4 KB  |  405 lines

  1. /* 
  2.  * desc.c --
  3.  *
  4.  *    File descriptor manipulation routines for the lfsrecov program.
  5.  *
  6.  * Copyright 1991 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that this copyright
  10.  * notice appears in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/proto.c,v 1.5 91/02/09 13:24:44 ouster Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include "lfslib.h"
  21. #include <stdio.h>
  22. #include <sys/types.h>
  23. #include <sys/file.h>
  24. #include <option.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <alloca.h>
  28. #include <bstring.h>
  29. #include <unistd.h>
  30. #include <bit.h>
  31. #include <time.h>
  32. #include <sys/time.h>
  33. #include <assert.h>
  34. #include <hash.h>
  35. #include <libc.h>
  36.  
  37. #include "lfsrecov.h"
  38. #include "desc.h"
  39.  
  40. /*
  41.  * descHashTable -
  42.  * Hash table data structures used to record the addresses of inode
  43.  * written out to the log.
  44.  * descHashHashTableInit - 
  45.  * Set to TRUE when the hash table startEntryHashTable has been initialized.
  46.  */
  47. static Hash_Table descHashTable;
  48. static Boolean    descHashTableInit = FALSE;
  49.  
  50. typedef struct NewDescValue { 
  51.     int address;        /* Disk address of descriptor or address
  52.                  * of delete record. */
  53.     LfsFileDescriptor *descPtr;    /* New LfsFileDescriptor. NIL if deleted*/
  54. } NewDescValue;
  55.  
  56.  
  57. /*
  58.  *----------------------------------------------------------------------
  59.  *
  60.  * RecordNewDesc --
  61.  *
  62.  *    Record the address of file descriptor.
  63.  *
  64.  * Results:
  65.  *    None.
  66.  *
  67.  * Side effects:
  68.  *    An entry is made in the startEntryHashTable.
  69.  *
  70.  *----------------------------------------------------------------------
  71.  */
  72.  
  73. void
  74. RecordNewDesc(fileNumber, address, descPtr)
  75.     int    fileNumber;    /* File number of descriptor. */
  76.     int    address;    /* Disk address of descriptor. FSDM_NIL_INDEX if
  77.              * descriptor being delete. */
  78.     LfsFileDescriptor *descPtr; /* New descriptor. */
  79. {
  80.     Hash_Entry *hentryPtr;
  81.     NewDescValue    *valuePtr;
  82.     Boolean new;
  83.  
  84.  
  85.     if (!descHashTableInit) {
  86.     Hash_InitTable(&descHashTable, 0, HASH_ONE_WORD_KEYS);
  87.     descHashTableInit = TRUE;
  88.     } 
  89.  
  90.     hentryPtr = Hash_CreateEntry(&descHashTable, (Address) fileNumber, 
  91.                 &new);
  92.     if (!new) { 
  93.     valuePtr = (NewDescValue *) Hash_GetValue(hentryPtr);
  94.     } else {
  95.     valuePtr = (NewDescValue *) malloc(sizeof(NewDescValue));
  96.     valuePtr->descPtr = (LfsFileDescriptor *) NIL;
  97.     }
  98.     if (descPtr == (LfsFileDescriptor *) NIL) {
  99.     if (valuePtr->descPtr != (LfsFileDescriptor *) NIL) {
  100.         free((char *) (valuePtr->descPtr));
  101.     }
  102.     valuePtr->address = address;
  103.     valuePtr->descPtr = descPtr;
  104.     } else {
  105.     if (valuePtr->descPtr == (LfsFileDescriptor *) NIL) {
  106.         valuePtr->descPtr = (LfsFileDescriptor *) 
  107.             malloc(sizeof(LfsFileDescriptor));
  108.     } 
  109.     valuePtr->address = address;
  110.     bcopy((char *) descPtr, (char *) (valuePtr->descPtr), 
  111.             sizeof(LfsFileDescriptor));
  112.     }
  113.     Hash_SetValue(hentryPtr, (ClientData)valuePtr);
  114.     return;
  115. }
  116.  
  117.  
  118.  
  119. /*
  120.  *----------------------------------------------------------------------
  121.  *
  122.  * FindNewDesc --
  123.  *
  124.  *    Find the new location of a inode.  
  125.  *
  126.  * Results:
  127.  *    TRUE if the inode's address is found. FALSE if no entry
  128.  *     was record under that fileNumber.
  129.  *
  130.  * Side effects:
  131.  *
  132.  *----------------------------------------------------------------------
  133.  */
  134.  
  135. Boolean
  136. FindNewDesc(fileNumber, addrPtr, descPtrPtr)
  137.     int        fileNumber;    /* FileNubmer of entry we wish to lookup.*/
  138.     int        *addrPtr;    /* OUT: Address of start entry record. */
  139.     LfsFileDescriptor **descPtrPtr; /* OUT: Current file descriptor. */
  140. {
  141.  
  142.     Hash_Entry *hentryPtr;
  143.     NewDescValue    *valuePtr;
  144.  
  145.     if (!descHashTableInit) {
  146.     Hash_InitTable(&descHashTable, 0, HASH_ONE_WORD_KEYS);
  147.     descHashTableInit = TRUE;
  148.     } 
  149.     hentryPtr = Hash_FindEntry(&descHashTable, (Address)fileNumber);
  150.     if (hentryPtr == (Hash_Entry *) NULL) {
  151.     return FALSE;
  152.     }
  153.     valuePtr = (NewDescValue *) Hash_GetValue(hentryPtr);
  154.     (*addrPtr) = valuePtr->address;
  155.     (*descPtrPtr) = valuePtr->descPtr;
  156.     return TRUE;
  157. }
  158.  
  159. /*
  160.  *----------------------------------------------------------------------
  161.  *
  162.  * ScanNewDesc --
  163.  *
  164.  *    Scan the list of descriptors in the recovery log.
  165.  *
  166.  * Results:
  167.  *    TRUE if more descriptors left. 
  168.  *    FALSE if scan is done.
  169.  *
  170.  * Side effects:
  171.  *    None.
  172.  *
  173.  *----------------------------------------------------------------------
  174.  */
  175.  
  176.  
  177. Boolean
  178. ScanNewDesc(clientDataPtr, fileNumberPtr, addressPtr, descPtrPtr)
  179.     ClientData    *clientDataPtr;    /* Pointer to storage for this routine.
  180.                  * MUST be initialized to NIL at start
  181.                  * of scan. */
  182.     int        *fileNumberPtr; /* OUT: filenumber of descriptor. */
  183.     int        *addressPtr;    /* OUT: Disk address of descriptor. */
  184.     LfsFileDescriptor **descPtrPtr; /* OUT: New value of descriptor. NIL if
  185.                       * descriptor has been deleted.
  186.                       */
  187. {
  188.     Hash_Entry *hentryPtr;
  189.     Hash_Search  *searchPtr;
  190.     NewDescValue    *valuePtr;
  191.  
  192.     if ((*clientDataPtr) == (ClientData) NIL) {
  193.     searchPtr = (Hash_Search *) malloc(sizeof(Hash_Search));
  194.     hentryPtr = Hash_EnumFirst(&descHashTable, searchPtr);
  195.     (*clientDataPtr) = (ClientData) searchPtr;
  196.     } else {
  197.     searchPtr = (Hash_Search *) (*clientDataPtr);
  198.     hentryPtr = Hash_EnumNext(searchPtr);
  199.     }
  200.     if (hentryPtr == (Hash_Entry *) NULL) {
  201.     free((char *) searchPtr);
  202.     (*clientDataPtr) = (ClientData) NIL;
  203.     return FALSE;
  204.     }
  205.     valuePtr = (NewDescValue *) Hash_GetValue(hentryPtr);
  206.     (*fileNumberPtr) = (int) (hentryPtr->key.ptr);
  207.     (*addressPtr) = valuePtr->address;
  208.     (*descPtrPtr) = valuePtr->descPtr;
  209.     return TRUE;
  210. }
  211.  
  212. /*
  213.  *----------------------------------------------------------------------
  214.  *
  215.  * ScanNewDescEnd --
  216.  *
  217.  *    End a scan of the active descriptor list.
  218.  *
  219.  * Results:
  220.  *    None.
  221.  *
  222.  * Side effects:
  223.  *    None.
  224.  *
  225.  *----------------------------------------------------------------------
  226.  */
  227. void
  228. ScanNewDescEnd(clientDataPtr)
  229. ClientData    *clientDataPtr;  /* Clientdata from ScanNewDesc. */
  230. {
  231.     if ((*clientDataPtr) != (ClientData) NIL) {
  232.     free((char *) (*clientDataPtr));
  233.     }
  234. }
  235.  
  236. #define UNREF_DESC_GROW_SIZE    100
  237. static int *unrefDescArray;
  238. static int unrefDescArraySize = 0;
  239. static int nextEntryToUse = 0;
  240.  
  241.  
  242. /*
  243.  *----------------------------------------------------------------------
  244.  *
  245.  * RecordUnrefDesc --
  246.  *
  247.  *    Record a file descriptor as possibly being unreferenced.
  248.  *
  249.  * Results:
  250.  *    None
  251.  *
  252.  * Side effects:
  253.  *    FileName is added to list.
  254.  *
  255.  *----------------------------------------------------------------------
  256.  */
  257. void
  258. RecordUnrefDesc(fileNumber, dirFileNumber, dirEntryPtr)
  259.     int    fileNumber;    /* Unreference file number. */
  260.     int dirFileNumber;
  261.     Fslcl_DirEntry *dirEntryPtr;
  262. {
  263.     if (nextEntryToUse >= unrefDescArraySize) {
  264.     int    oldSize = unrefDescArraySize;
  265.     unrefDescArraySize += UNREF_DESC_GROW_SIZE;
  266.     if (oldSize == 0) {
  267.         unrefDescArray = (int *) malloc(unrefDescArraySize * sizeof(int));
  268.     } else {
  269.         unrefDescArray = (int *) realloc((char *) unrefDescArray, 
  270.                 unrefDescArraySize * sizeof(int));
  271.     }
  272.     }
  273.     unrefDescArray[nextEntryToUse] = fileNumber;
  274.     nextEntryToUse++;
  275. }
  276.  
  277.  
  278. /*
  279.  *----------------------------------------------------------------------
  280.  *
  281.  * ScanUnrefDesc --
  282.  *
  283.  *    Scan the list of descriptors left unreferences..
  284.  *
  285.  * Results:
  286.  *    TRUE if more descriptors left. 
  287.  *    FALSE if scan is done.
  288.  *
  289.  * Side effects:
  290.  *    None.
  291.  *
  292.  *----------------------------------------------------------------------
  293.  */
  294.  
  295.  
  296. Boolean
  297. ScanUnrefDesc(clientDataPtr, fileNumberPtr)
  298.     ClientData    *clientDataPtr;    /* Pointer to storage for this routine.
  299.                  * MUST be initialized to NIL at start
  300.                  * of scan. */
  301.     int        *fileNumberPtr; /* OUT: filenumber of descriptor. */
  302. {
  303.     int    startIndex;
  304.  
  305.     if ((*clientDataPtr) == (ClientData) NIL) {
  306.     startIndex = 0;
  307.     } else {
  308.     startIndex = (int) (*clientDataPtr);
  309.     }
  310.     if (startIndex < nextEntryToUse) {
  311.     (*fileNumberPtr) = unrefDescArray[startIndex];
  312.     startIndex++;
  313.     (*clientDataPtr) = (ClientData) startIndex;
  314.     return TRUE;
  315.     }
  316.     return FALSE;
  317.  
  318. }
  319.  
  320.  
  321. /*
  322.  *----------------------------------------------------------------------
  323.  *
  324.  * ScanUnrefDescEnd --
  325.  *
  326.  *    End a scan of the unreferenced desc.
  327.  *
  328.  * Results:
  329.  *    None.
  330.  *
  331.  * Side effects:
  332.  *    None.
  333.  *
  334.  *----------------------------------------------------------------------
  335.  */
  336. void
  337. ScanUnrefDescEnd(clientDataPtr)
  338. ClientData    *clientDataPtr;  /* Clientdata from ScanNewDesc. */
  339. {
  340. }
  341.  
  342.  
  343. /*
  344.  *----------------------------------------------------------------------
  345.  *
  346.  * RecovDescMapSummary --
  347.  *
  348.  *    Check the segment summary regions for the desc map. For recovery
  349.  *    we do nothing.
  350.  *
  351.  * Results:
  352.  *    None.
  353.  *
  354.  * Side effects:
  355.  *    None.
  356.  *
  357.  *----------------------------------------------------------------------
  358.  */
  359. void
  360. RecovDescMapSummary(lfsPtr, pass, segPtr, startAddress, offset, 
  361.             segSummaryHdrPtr) 
  362.     Lfs    *lfsPtr;    /* File system description. */
  363.     enum Pass pass;    /* Pass number of recovery. */
  364.     LfsSeg *segPtr;    /* Segment being examined. */
  365.     int startAddress;   /* Starting address being examined. */
  366.     int offset;        /* Offset into segment being examined. */
  367.     LfsSegSummaryHdr *segSummaryHdrPtr; /* Summary header pointer */
  368. {
  369.     int blocks, *blockArray, i, startAddr, fsBlocks;
  370.  
  371.     if (pass == PASS2) {
  372.     /*
  373.      * Ignore desc map blocks during pass2 recovery.   These don't
  374.      * contain anything we wont recovery already with the current
  375.      * algorithm except may be more up to date access times.  
  376.      */
  377.     return;
  378.     }
  379.     /*
  380.      * PASS1, Check to make sure that things look correct.
  381.      */
  382.     fsBlocks = lfsPtr->superBlock.descMap.stableMem.blockSize/blockSize;
  383.     blocks = (segSummaryHdrPtr->lengthInBytes - sizeof(LfsSegSummaryHdr)) /
  384.                 sizeof(int);
  385.     if (blocks * fsBlocks != segSummaryHdrPtr->numDataBlocks) {
  386.     fprintf(stderr,"%s:RecovDescMapSummary: Wrong block count; is %d should be %s\n", deviceName,blocks * fsBlocks, segSummaryHdrPtr->numDataBlocks);
  387.     }
  388.     blockArray = (int *) (segSummaryHdrPtr + 1);
  389.     for (i = 0; i < blocks; i++) {
  390.     startAddr = startAddress - i * fsBlocks - fsBlocks;
  391.     if ((blockArray[i] < 0) || 
  392.         (blockArray[i] > lfsPtr->superBlock.descMap.stableMem.maxNumBlocks)){
  393.        fprintf(stderr,"%s:RecovDescMapSummary: Bad block number %d at %d\n",
  394.             deviceName,blockArray[i], startAddr);
  395.         continue;
  396.     }
  397.     if (showLog) {
  398.         printf("Addr %d DescMap Block %d\n", startAddr, blockArray[i]);
  399.     }
  400.     }
  401.     stats.descMapBlocks += blocks;
  402.  
  403. }
  404.  
  405.